#include "intensityManager.h"
#include "DeckLinkAPI.h"

#include <iostream>
#include <string.h>
#include <sstream>


using namespace std;

void IntensityManager::dPrint(string data)
{

	string output="[IntensityManager] " + data;

//	cout << output << endl;
};


IntensityManager::IntensityManager()
{
	deckLinkIterator = CreateDeckLinkIteratorInstance();
	
	if (deckLinkIterator==NULL)
	{
		dPrint("DeckLinkIterator couldn't be created");
		
	}
	else
	{
		dPrint("DeckLinkIterator created");
		
	}
	
};



void IntensityManager::checkDevices()
{
	
	if (deckLinkIterator!=NULL)
	{
		while(deckLinkIterator->Next(&device)==S_OK)
		{
			char *device_name;
			device->GetModelName((const char**)&device_name);
			char output[200]="'";
			strcat(output,device_name);
			strcat(output,"' found");
			dPrint(output);
			
		}
	}
	else
	{
		dPrint("DeckLinkIterator not initializated");
	}

};

void IntensityManager::connectIntensity()
{

	if (deckLinkIterator!=NULL)
	{
		while(deckLinkIterator->Next(&device)==S_OK)
		{
			char *device_name;
			device->GetModelName((const char**)&device_name);
			if (strcmp(device_name,"Intensity Pro")==0)
			{
				dPrint("Connected to Intensity Pro");
				break;
			
			}
			
			dPrint("Found another DeckLink device. Checking the next one...");
			
		}
	}
	else
	{
		dPrint("DeckLinkIterator not initializated");
	}	
	
	
};

void IntensityManager::getOutputManager()
{
	
	if (device!=NULL)
	{
		int result=device->QueryInterface(IID_IDeckLinkOutput, (void**)&output);
		if (result==S_OK)
			dPrint("Getting Intensity Output Manager...");
		
		result==output->GetDisplayModeIterator(&displayIterator);
		
		if (result==S_OK)
			dPrint("Getting Display Iterator...");
		
	}
	else
	{
		
		dPrint("Device not initializated");
		
	}	
	
};


void IntensityManager::getInputManager()
{
	
	if (device!=NULL)
	{
		int result=device->QueryInterface(IID_IDeckLinkInput, (void**)&input);
		if (result==S_OK)
			dPrint("Getting Intensity Input Manager...");
		
		if (displayIterator==NULL)
		{
			result==input->GetDisplayModeIterator(&displayIterator);
			if (result==S_OK)
				dPrint("Getting Display Iterator...");
		}
		else
			dPrint("Display Mode Iterator already initializated");
		
	}
	else
	{
		
		dPrint("Device not initializated");
		
	}	
	
};

void IntensityManager::getDisplayModes()
{
	//IDeckLinkDisplayMode

	dPrint("Intensity Pro Display Modes:");

	if (displayIterator!=NULL)
	{
		IDeckLinkDisplayMode *display_mode;
		int count=0;
		while(displayIterator->Next(&display_mode)==S_OK)
		{
			char *data;
			display_mode->GetName((const char**)&data);
			string s;
			stringstream out;
			out << count;
			s = out.str();
			string output="\t [" + s + "] " + (string)data;
			dPrint(output);
			count++;
		}
	}
	else
		dPrint("Display Iterator not initializated");
		
	
};

void IntensityManager::setDisplayMode(int mode)
{

	int result;
	switch (mode)
	{
		case NTSC:
			dPrint("Initializing NTSC video mode...");
			input->EnableVideoInput(bmdModeNTSC, bmdFormat8BitYUV, 0);
			break;
		case NTSC2398:
			dPrint("Initializing NTSC 23.98fps video mode...");
			input->EnableVideoInput(bmdModeNTSC2398, bmdFormat8BitYUV, 0);			
			break;
		case PAL:
			dPrint("Initializing PAL video mode...");
			input->EnableVideoInput(bmdModePAL, bmdFormat8BitYUV, 0);
			break;
		case P1080_2398:
			dPrint("Initializing 1080p 23.98fps video mode...");
			input->EnableVideoInput(bmdModeHD1080p2398, bmdFormat8BitYUV, 0);
			break;
		case P1080_24:
			dPrint("Initializing 1080p 24fps video mode...");
			input->EnableVideoInput(bmdModeHD1080p24, bmdFormat8BitYUV, 0);
			break;
		case P1080_25:
			dPrint("Initializing 1080p 25fps video mode...");
			input->EnableVideoInput(bmdModeHD1080p25, bmdFormat8BitYUV, 0);
			break;
		case P1080_2997:
			dPrint("Initializing 1080p 29.97fps video mode...");
			input->EnableVideoInput(bmdModeHD1080p2997, bmdFormat8BitYUV, 0);
			break;
		case P1080_30:
			dPrint("Initializing 1080p 30fps video mode...");
			input->EnableVideoInput(bmdModeHD1080p30, bmdFormat8BitYUV, 0);
			break;
		case I1080_50:
			dPrint("Initializing 1080i 50fps video mode...");
			input->EnableVideoInput(bmdModeHD1080i50, bmdFormat8BitYUV, 0);
			break;
		case I1080_5994:
			dPrint("Initializing 1080i 59.94fps video mode...");
			input->EnableVideoInput(bmdModeHD1080i5994, bmdFormat8BitYUV, 0);
			break;
		case I1080_60:
			dPrint("Initializing 1080i 60fps video mode...");
			input->EnableVideoInput(bmdModeHD1080i6000, bmdFormat8BitYUV, 0);
			break;
		case P720_50:
			dPrint("Initializing 720p 50fps video mode...");
			input->EnableVideoInput(bmdModeHD720p50, bmdFormat8BitYUV, 0);
			break;
		case P720_5994:
			dPrint("Initializing 720p 59.94fps video mode...");
			int result2;
			result2=input->EnableAudioInput(bmdAudioSampleRate48kHz, 16, 2);
			if (result2==S_OK)
			{
				dPrint("Audio Mode Initializated");
			}
			result=input->EnableVideoInput(bmdModeHD720p5994, bmdFormat8BitYUV, 0);
			if (result==S_OK)
			{
				dPrint("Video Mode Initializated");
			}			
			result=input->StartStreams();
			if (result==S_OK)
			{
				dPrint("Stream Initializated");
			}
			if (result==E_UNEXPECTED)
				dPrint("Stream error");
			if (result==E_ACCESSDENIED)
				dPrint("denied");
			if (result==E_FAIL)
				dPrint("FAIL!");
			break;
		case P720_60:
			dPrint("Initializing 720p 60fps video mode...");
			input->EnableVideoInput(bmdModeHD720p60, bmdFormat8BitYUV, 0);
			
			
			break;
			
		default:
		
			dPrint("Unknown video mode");
			break;
		
	}
	
	
	result=input->StartStreams();
	if (result==S_OK)
	{
			dPrint("Video Mode Initializated");
	}
	
};
